﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mighty.Common;
using System.Collections;

namespace Mighty.Brain
{
    public class MSBrain : BasicBrain
    {
        /// <summary>
        /// 각 플레이어가 가지게 되는 게임에 대한 정보, 각 이벤트가 호출되기 전에 gameInfo에는 항상 최신의 정보가
        /// 업데이트되어 있다
        /// </summary>
        /// 

        //every cards -> list
        /*

        public enum usedtype { have, used, none };
        public class cardlist
        {

            usedtype usedtype;

        }

        public cardlist[,] cardlist = new cardlist[4, 15]; */

        int cnt_clover = 0, cnt_diamond = 0, cnt_heart = 0, cnt_spade = 0;
        int cnt_clover_dom = 0, cnt_diamond_dom = 0, cnt_heart_dom = 0, cnt_spade_dom = 0;
        float cnt_clover_calc = 0, cnt_diamond_calc = 0, cnt_heart_calc = 0, cnt_spade_calc = 0;
        float max_calc;
        int min;
        int get_joker = 0, get_mighty = 0;

        /// <summary>
        /// 게임시작
        ///  * 매 게임마다 초기화해야할 코드가 있다면 여기에 넣어라
        /// </summary>




        public override void GameStartEvent()
        {






            int i;




            //counting shapes :: int cnt_shape

            for (i = 0; i < 10; i++)
            {
                if (gameInfo.myCards[i].shape == Shape.Clover)
                    cnt_clover++;
                else if (gameInfo.myCards[i].shape == Shape.Diamond)
                    cnt_diamond++;
                else if (gameInfo.myCards[i].shape == Shape.Heart)
                    cnt_heart++;
                else if (gameInfo.myCards[i].shape == Shape.Spade)
                    cnt_spade++;
            }

            //counting the strong shape&pic :: int cnt_shape_dom

            for (i = 0; i < 10; i++)
            {
                if (gameInfo.myCards[i].shape == Shape.Clover && gameInfo.myCards[i].number >= 12)
                    cnt_clover_dom += gameInfo.myCards[i].number;
                else if (gameInfo.myCards[i].shape == Shape.Diamond)
                    cnt_diamond_dom += gameInfo.myCards[i].number;
                else if (gameInfo.myCards[i].shape == Shape.Heart)
                    cnt_heart_dom += gameInfo.myCards[i].number;
                else if (gameInfo.myCards[i].shape == Shape.Spade)
                    cnt_spade_dom += gameInfo.myCards[i].number;
            }


            //calulate to select giruda :: cnt_shape_calc   

            cnt_clover_calc = (float)cnt_clover_dom / 10 + cnt_clover;
            cnt_diamond_calc = (float)cnt_diamond_dom / 10 + cnt_diamond;
            cnt_heart_calc = (float)cnt_heart_dom / 10 + cnt_heart;
            cnt_spade_calc = (float)cnt_spade_dom / 10 + cnt_spade;


            //determine the strongest shape :: max_calc

            max_calc = cnt_clover_calc;
            if (max_calc < cnt_diamond_calc)
                max_calc = cnt_diamond_calc;
            if (max_calc < cnt_heart_calc)
                max_calc = cnt_heart_calc;
            if (max_calc < cnt_spade_calc)
                max_calc = cnt_heart_calc;

            //determine the larest shape :: int max
            min = cnt_clover;

            if (min < cnt_diamond)
                min = cnt_diamond;
            if (min < cnt_heart)
                min = cnt_heart;
            if (min < cnt_spade)
                min = cnt_heart;









        }

        /// <summary>
        /// 베팅시작
        ///  * 카드를 나누어 주고 호출된다. gameInfo.myCards를 참고
        /// </summary>
        public override void BettingReadyEvent()
        {
        }

        /// <summary>
        /// 베팅차례
        ///  * 지금까지 배팅된 정보(gameInfo.bettingHistory) 또는 마지막 pass가 아닌 베팅정보 gameInfo.betting를 참고하여 베팅을 결정한다
        /// </summary>
        /// <remarks>
        /// [기본행동] 베팅리밋(betting.limit)이 15이하 이면 베팅리밋을 +1하고 노기루다(Giruda.NoGiruda)로 베팅한다
        /// </remarks>
        public override Betting BettingTicEvent()
        {
            Betting betting = new Betting();

            betting.isPass = true;
            if (gameInfo.betting.limit < 15)
            {
                betting.isPass = false;

                // select giruda by dom
                if (max_calc == cnt_clover_calc)
                    betting.giruda = Giruda.Clover;
                if (max_calc == cnt_diamond_calc)
                    betting.giruda = Giruda.Diamond;
                if (max_calc == cnt_heart_calc)
                    betting.giruda = Giruda.Heart;
                if (max_calc == cnt_spade_calc)
                    betting.giruda = Giruda.Spade;

                //

                if (gameInfo.betting.limit < 14)
                {
                    betting.limit = 14;
                }
                if (gameInfo.betting.limit == 14)
                    betting.limit = 15;
            }

            return betting;
        }


        /// <summary>
        /// 다른사람의 베팅 정보
        /// </summary>
        public override void BettingTalkEvent()
        {
        }

        /// <summary>
        /// 베팅완료, 주공이 정해졌다. 베팅이 끝났을 경우 처리할 코드가 있다면 여기에 하라.
        /// </summary>
        public override void BettingCompleteEvent()
        {
        }

        /// <summary>
        /// (주공)카드선택, 13장의 카드중 10장의 카드선택. 버릴3장의 카드에 cmdRemove=true로 설정해주어야 한다
        /// 만약 정확히 3장의 카드가 선택되지 않았을 경우에는 새로추가된 3장의 카드가 그대로 버려진다.
        /// ChoiceCardEvent 가 호출된 후에는 선택된 10장의 카드는 myCards[0]부터 차례대로 배치되고 버려진 3장의 카드는
        /// myCards[10]에서부터 배치되어 나중에 어떤 카드가 버려졌는지 알수 있게 해준다
        /// </summary>
        /// <remarks>
        /// [기본행동] 추가된 3장의 카드를 그대로 버린다
        /// </remarks>
        public override HandedCard[] ChoiceCardEvent()
        {
            // remove cards
            int cnt_removed = 0;
            int i;
            for (i = 0; i < 13; i++)
            {
                gameInfo.myCards[i].cmdRemove = false;
            }

            //10, J remove

            for (i = 0; i < 13; i++)
            {
                if (gameInfo.myCards[i].number == 10 || gameInfo.myCards[i].number == 11)
                {
                    if (gameInfo.betting.giruda == Giruda.Clover && gameInfo.myCards[i].shape != Shape.Clover && cnt_removed < 3 && gameInfo.myCards[i].cmdRemove == false)
                    {
                        gameInfo.myCards[i].cmdRemove = true;
                        cnt_removed++;
                    }
                    if (gameInfo.betting.giruda == Giruda.Diamond && gameInfo.myCards[i].shape != Shape.Diamond && cnt_removed < 3 && gameInfo.myCards[i].cmdRemove == false)
                    {
                        gameInfo.myCards[i].cmdRemove = true;
                        cnt_removed++;
                    }
                    if (gameInfo.betting.giruda == Giruda.Heart && gameInfo.myCards[i].shape != Shape.Heart && cnt_removed < 3 && gameInfo.myCards[i].cmdRemove == false)
                    {
                        gameInfo.myCards[i].cmdRemove = true;
                        cnt_removed++;
                    }
                    if (gameInfo.betting.giruda == Giruda.Spade && gameInfo.myCards[i].shape != Shape.Spade && cnt_removed < 3 && gameInfo.myCards[i].cmdRemove == false)
                    {
                        gameInfo.myCards[i].cmdRemove = true;
                        cnt_removed++;
                    }
                }
            }

            //small shape remove

            while (cnt_removed < 3)
            {
                for (i = 0; i < 13; i++)
                {
                    if (gameInfo.myCards[i].shape == Shape.Clover && gameInfo.betting.giruda != Giruda.Clover && cnt_clover == min && cnt_removed < 3 && gameInfo.myCards[i].cmdRemove == false)
                    {
                        gameInfo.myCards[i].cmdRemove = true;
                        cnt_removed++;
                    }
                    if (gameInfo.myCards[i].shape == Shape.Diamond && gameInfo.betting.giruda != Giruda.Diamond && cnt_diamond == min && cnt_removed < 3 && gameInfo.myCards[i].cmdRemove == false)
                    {
                        gameInfo.myCards[i].cmdRemove = true;
                        cnt_removed++;
                    }
                    if (gameInfo.myCards[i].shape == Shape.Heart && gameInfo.betting.giruda != Giruda.Heart && cnt_heart == min && cnt_removed < 3 && gameInfo.myCards[i].cmdRemove == false)
                    {
                        gameInfo.myCards[i].cmdRemove = true;
                        cnt_removed++;
                    }
                    if (gameInfo.myCards[i].shape == Shape.Spade && gameInfo.betting.giruda != Giruda.Spade && cnt_spade == min && cnt_removed < 3 && gameInfo.myCards[i].cmdRemove == false)
                    {
                        gameInfo.myCards[i].cmdRemove = true;
                        cnt_removed++;
                    }
                }

                min++;
            }


            for (i = 0; i < 13; i++)
            {
                if (gameInfo.myCards[i].shape == Shape.Joker)
                    get_joker = 1;
                if (gameInfo.myCards[i].shape == Shape.Spade && gameInfo.betting.giruda != Giruda.Spade && gameInfo.myCards[i].number == 14)
                    get_mighty = 1;
                if (gameInfo.myCards[i].shape == Shape.Diamond && gameInfo.betting.giruda == Giruda.Spade && gameInfo.myCards[i].number == 14)
                    get_mighty = 1;

            }

            return gameInfo.myCards;
        }

        /// <summary>
        /// 최종베팅정보, 기루다무늬변경가능. 기루다를 변경할 경우 최소+2된 limit정보를 리턴해야 한다
        /// </summary>
        /// <remarks>
        /// [기본행동] 아무런 변경도 하지 않는다
        /// </remarks>
        public override Betting LastBettingEvent()
        {
            return gameInfo.betting;
        }

        /// <summary>
        /// 주공의 최종베팅정보
        /// </summary>
        public override void LastBettingTalkEvent()
        {
        }

        /// <summary>
        /// (주공)프랜드선택. 프랜드를 선택하는 방법은 노프랜드(FriendPlayer.HowToSelect.nofriend),
        /// 초구프랜드(FriendPlayer.HowToSelect.firstwin),카드프랜드(FriendPlayer.HowToSelect.card)가 있다.
        /// </summary>
        /// <remarks>
        /// [기본행동] 초구프랜드를 선택한다
        /// </remarks>
        public override FriendPlayer ChoiceFriendEvent()
        {
            FriendPlayer friend_player = new FriendPlayer();
            if (get_mighty == 0)
            {
                friend_player.howToSelect = FriendPlayer.HowToSelect.card;
                friend_player.cardCondition = new Card(Shape.Spade, 14);
            }
            else if (get_mighty == 1 && get_joker == 0)
            {
                friend_player.howToSelect = FriendPlayer.HowToSelect.card;
                friend_player.cardCondition = new Card(Shape.Joker, 0);
            }
            else
                friend_player.howToSelect = FriendPlayer.HowToSelect.firstwin;


            return friend_player;
        }

        /// <summary>
        /// 주공의 프랜드 정보
        /// </summary>
        public override void ChoiceFriendTalkEvent()
        {
        }

        /// <summary>
        /// 각라운드의시작
        ///  * 매라운드마다 초기화할 코드가 있다면 이부분에 들어가게 된다
        /// </summary>
        public override void RoundReadyEvent()
        {

        }

        /// <summary>
        /// 카드낼차례
        ///  * 각 사용자의 턴에 한번씩 호출되며 낼 카드를 결과값으로 리턴해야 한다. 
        ///  * 사용가능한 카드에는 myCards[i].isPossible 속성이 true로 설정되어 있다. 
        ///  * 만약 사용불가능한 카드를 낼 경우에 시스템은 카드배열에서 제일 처음 만나는 사용가능한 카드를 골라서 사용한다
        /// </summary>
        /// <remarks>
        /// [기본행동] 가능한 카드중에서 랜덤하게 하나의 카드를 선택한다
        /// </remarks>
        public override HandedCard RoundTicEvent()
        {
            ArrayList possibleCards = new ArrayList();
            foreach (HandedCard card in gameInfo.myCards)
            {
                if (card.isPossible) possibleCards.Add(card);
            }

            Random r = new Random();
            int k = r.Next(possibleCards.Count);

            return (HandedCard)possibleCards[k];
        }

        /// <summary>
        /// 다른사람의 카드 정보
        /// </summary>
        public override void RoundCardThrowEvent()
        {
        }

        /// <summary>
        /// 각라운드의종료, 각 라운드가 종료되면 호출된다. 각 라운드의 승자는 gameinfo의 winner를 참조한다
        /// </summary>
        public override void RoundCompleteEvent()
        {

        }

        /// <summary>
        /// 게임의 종료, 게임이 종료되었을때 실행될 코드는 여기에 추가한다.
        /// </summary>
        public override void GameEndEvent()
        {

        }
    }
}